import type { ChildProcessReturn, ReadDirOptions, RendererChildProcessInvoker, RendererFileSystem } from "@common/ipc-types.ts";
import { ipcInvoker } from "./electron.ts";
import type fsp from "node:fs/promises";

export const fsInvoker: RendererFileSystem = {
  exists(path: string): Promise<boolean> {
    return ipcInvoker.invoke("fs.exists", path);
  },
  exists1(path: string): Promise<boolean> {
    return ipcInvoker.invoke("fs.exists1", path);
  },
  readFile(...args: Parameters<typeof fsp.readFile>): Promise<Uint8Array> {
    return ipcInvoker.invoke("fs.readFile", ...args);
  },
  readFileText(...args: Parameters<typeof fsp.readFile>): Promise<string> {
    return ipcInvoker.invoke("fs.readFileText", ...args);
  },
  readFileJson<T = any>(...args: Parameters<typeof fsp.readFile>): Promise<T> {
    return ipcInvoker.invoke("fs.readFileJson", ...args);
  },
  writeFile(...args: Parameters<typeof fsp.writeFile>): Promise<void> {
    return ipcInvoker.invoke("fs.writeFile", ...args);
  },
  async writeBlob(file: string, blob: Blob): Promise<void> {
    const buffer = await blob.arrayBuffer();
    return await ipcInvoker.invoke("fs.writeFile", file, new Uint8Array(buffer));
  },
  mkdir(...args: Parameters<typeof fsp.mkdir>): Promise<string | undefined> {
    return ipcInvoker.invoke("fs.mkdir", ...args);
  },
  rm(...args: Parameters<typeof fsp.rm>): Promise<void> {
    return ipcInvoker.invoke("fs.rm", ...args);
  },
  copyFile(...args: Parameters<typeof fsp.copyFile>): Promise<void> {
    return ipcInvoker.invoke("fs.copyFile", ...args);
  },
  cp(...args: Parameters<typeof fsp.cp>): Promise<void> {
    return ipcInvoker.invokeNode("node:fs/promises.cp", ...args);
  },
  readdir(path: string, options?: ReadDirOptions): Promise<string[]> {
    return ipcInvoker.invoke("fs.readdir", path, options);
  },
  readlink(path: string): Promise<string> {
    return ipcInvoker.invokeNode("node:fs/promises.readlink", path);
  },
  symlink(...args: Parameters<typeof fsp.symlink>): Promise<void> {
    return ipcInvoker.invokeNode("node:fs/promises.symlink", ...args);
  },
  link(...args: Parameters<typeof fsp.link>): Promise<void> {
    return ipcInvoker.invokeNode("node:fs/promises.link", ...args);
  },
  unlink(...args: Parameters<typeof fsp.unlink>): Promise<void> {
    return ipcInvoker.invokeNode("node:fs/promises.unlink", ...args);
  },
  rename(...args: Parameters<typeof fsp.rename>): Promise<void> {
    return ipcInvoker.invokeNode("node:fs/promises.rename", ...args);
  },
};

export const cpInvoker: RendererChildProcessInvoker = {
  execCmd(cmd: string, options: import("node:child_process").ExecOptions = {}): Promise<ChildProcessReturn> {
    return ipcInvoker.invoke("cp.exec", cmd, options);
  },
  execCmdSudo(cmd: string, options?: import("node:child_process").ExecOptions): Promise<ChildProcessReturn> {
    return ipcInvoker.invoke("cp.execSudo", cmd, options);
  },
  spawn(cmd: string, args?: string[]): Promise<ChildProcessReturn> {
    return ipcInvoker.invoke("cp.spawn", cmd, args);
  },
  sudo(cmd: string, args?: string[]): Promise<ChildProcessReturn> {
    return ipcInvoker.invoke("cp.sudo", cmd, args);
  },
  execCmdTool(cmd: string, args?: string[]): Promise<ChildProcessReturn> {
    return ipcInvoker.invoke("cp.execCmdTool", cmd, args);
  },
  execCmdToolSudo(cmd: string, args?: string[]): Promise<ChildProcessReturn> {
    return ipcInvoker.invoke("cp.sudo.execCmdTool", cmd, args);
  },
  execFile(file: string, args?: string[], options?: import("node:child_process").ExecFileOptions): Promise<ChildProcessReturn> {
    return ipcInvoker.invoke("cp.execFile", file, args, options);
  },
};
